<template>
  <!-- 录制预览区域 -->
  <div class="preview-container">
    <div class="preview-wrapper">
      <video
        ref="previewVideoRef"
        class="preview-video"
        autoplay
        playsinline
        :class="{ hidden: !isVideoMode }"
      ></video>
      <div class="audio-visualizer" :class="{ hidden: isVideoMode }">
        <div class="audio-bars" ref="audioBarsRef"></div>
      </div>
      <div class="recording-indicator" v-if="recordStatus != RecorderStatus.READY">
        <div class="pulse-circle"></div>
        <span class="recording-text">正在录制...</span>
      </div>
    </div>

    <!-- 录制时长显示 -->
    <div class="recording-time" v-if="recordStatus !== RecorderStatus.READY">
      {{ formattedRecordingTime }}
    </div>
  </div>
</template>

<script setup lang="ts">
import { RecorderStatus } from '@renderer/types/enums/recoder.enum'
import { useImChatStore } from '@renderer/store'
const imChatStore = useImChatStore()
const previewVideoRef = ref<any>(null)
const audioBarsRef = ref<any>(null)
const recordingTime = ref(0)
const recordingTimer = ref<any>(null)
const recordStatus = computed(() => imChatStore.recordStatus)
const isVideoMode = computed(() => imChatStore.isVideoMode)

watch(
  () => recordStatus.value,
  (val) => {
    if (val === RecorderStatus.COMPLETE) {
      recordingTime.value = 0
      clearInterval(recordingTimer.value)
    } else if (val === RecorderStatus.RECORDING) {
      // 开始计时

      recordingTimer.value = setInterval(() => {
        recordingTime.value++
      }, 1000)
    } else if (val === RecorderStatus.PAUSE) {
      // 暂停计时
      clearInterval(recordingTimer.value)
    } else if (val === RecorderStatus.READY) {
      //如果是粘贴
      recordingTime.value = 0
      clearInterval(recordingTimer.value)
    }
  }
)
watch(
  () => imChatStore.mediaStream,
  (val) => {
    if (val) {
      // 1. 设置预览视频的媒体流
      if (previewVideoRef.value && isVideoMode.value) {
        previewVideoRef.value.srcObject = imChatStore.mediaStream
      }
      // 2. 音频可视化
      startAudioVisualization()
    }
  }
)
// 2. 音频可视化
const startAudioVisualization = () => {
  if (isVideoMode.value || !imChatStore.mediaStream) return

  try {
    // window.AudioContext 是 Web Audio API 的核心接口，用于处理和操纵音频数据，提供了复杂的音频处理能力，如音量控制、音频可视化、音效处理等。在语音录制场景中，它常被用来实现音频可视化、音量监测等功能。
    const audioContext = new window.AudioContext()
    const source = audioContext.createMediaStreamSource(imChatStore.mediaStream)
    const analyser = audioContext.createAnalyser()

    analyser.fftSize = 32
    source.connect(analyser)

    const bufferLength = analyser.frequencyBinCount
    const dataArray = new Uint8Array(bufferLength)

    // 创建音频 bars
    audioBarsRef.value.innerHTML = ''
    for (let i = 0; i < bufferLength; i++) {
      const bar = document.createElement('div')
      bar.className = 'audio-bar'
      audioBarsRef.value.appendChild(bar)
    }

    const bars = audioBarsRef.value.getElementsByClassName('audio-bar')

    // 动画循环更新音频可视化
    const updateVisualization = () => {
      if (
        recordStatus.value == RecorderStatus.READY ||
        isVideoMode.value ||
        !imChatStore.mediaStream
      )
        return

      requestAnimationFrame(updateVisualization)
      analyser.getByteFrequencyData(dataArray)

      for (let i = 0; i < bufferLength; i++) {
        const height = (dataArray[i] / 255) * 100
        bars[i].style.height = `${height}%`
      }
    }

    updateVisualization()
  } catch (error) {
    console.error('音频可视化失败:', error)
    ElMessage.error('音频可视化失败')
  }
}
const formattedRecordingTime = computed(() => {
  const minutes = Math.floor(recordingTime.value / 60)
  const seconds = recordingTime.value % 60
  return `${minutes.toString().padStart(2, '0')}:${seconds.toString().padStart(2, '0')}`
})
</script>

<style lang="scss" scoped>
.preview-container {
  position: relative;
  margin-bottom: 24px;

  .preview-wrapper {
    position: relative;
    width: 100%;
    padding-top: 56.25%; /* 16:9 Aspect Ratio */
    background-color: #000;
    border-radius: 8px;
    overflow: hidden;

    .preview-video {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      object-fit: cover;
      transition: opacity 0.3s ease;
    }

    .audio-visualizer {
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: #2c3e50;
      display: flex;
      align-items: center;
      justify-content: center;
      gap: 4px;
      transition: opacity 0.3s ease;

      .audio-bars {
        display: flex;
        align-items: center;
        justify-content: center;
        gap: 4px;
        width: 80%;
        height: 60%;

        .audio-bar {
          width: 6px;
          background-color: #3498db;
          border-radius: 3px;
          transition: height 0.1s ease;
        }
      }
    }

    .recording-indicator {
      position: absolute;
      bottom: 16px;
      left: 16px;
      display: flex;
      align-items: center;
      gap: 8px;
      color: white;
      background-color: rgba(0, 0, 0, 0.5);
      padding: 4px 12px;
      border-radius: 16px;
      font-size: 14px;

      .pulse-circle {
        width: 8px;
        height: 8px;
        border-radius: 50%;
        background-color: #ff3b30;
        animation: pulse 1.5s infinite;
      }
    }

    .hidden {
      opacity: 0;
      pointer-events: none;
      position: absolute;
    }
  }

  .recording-time {
    text-align: center;
    font-size: 20px;
    font-weight: 500;
    margin-top: 12px;
    color: #2c3e50;
  }
}
@keyframes pulse {
  0% {
    opacity: 1;
    transform: scale(1);
  }
  50% {
    opacity: 0.5;
    transform: scale(1.1);
  }
  100% {
    opacity: 1;
    transform: scale(1);
  }
}

@media (max-width: 600px) {
  .media-recorder {
    padding: 16px;
  }

  .recorder-header {
    flex-direction: column;
    align-items: flex-start;
    gap: 12px;
  }

  .control-buttons {
    gap: 12px;
  }

  .primary-btn {
    width: 60px;
    height: 60px;
  }
}
</style>
